package mylittleinvestigations.CaseInformation;

import java.awt.image.BufferedImage;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Stack;
import javax.imageio.ImageIO;
import mylittleinvestigations.Base64;
import org.newdawn.slick.Color;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.geom.Polygon;

public class CaseXmlWriter
{
    private static final String TabString = "    ";
    
    private Stack<String> elementNameStack;
    private BufferedWriter writer;
    
    public CaseXmlWriter(BufferedWriter writer) throws IOException
    {
        this.elementNameStack = new Stack<String>();
        this.writer = writer;
        
        this.writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        //this.writer.newLine();
    }
    
    public void StartElement(String name/*, String ... attributes*/) throws IOException
    {
        /*if (attributes.length % 2 != 0)
        {
            throw new IllegalArgumentException("Must be an even number of attributes.");
        }*/
        
        //this.WriteTabs();
        this.writer.write("<");
        this.writer.write(name);
        
        /*for (int i = 0; i < attributes.length; i += 2)
        {
            this.writer.write(" ");
            this.writer.write(attributes[i]);
            this.writer.write("=\"");
            this.writer.write(attributes[i + 1]);
            this.writer.write("\"");
        }*/
        
        this.writer.write(">");
        //this.writer.newLine();
        
        this.elementNameStack.add(name);
    }
    
    public void WriteIntElement(String elementName, int elementValue) throws IOException
    {
        this.WriteTextElement(elementName, "" + elementValue);
    }
    
    public void WriteDoubleElement(String elementName, double elementValue) throws IOException
    {
        this.WriteTextElement(elementName, "" + elementValue);
    }
    
    public void WriteBooleanElement(String elementName, boolean elementValue) throws IOException
    {
        this.WriteTextElement(elementName, "" + elementValue);
    }
    
    public void WriteSpriteId(String elementName, String spriteId) throws IOException
    {
        Case.getInstance().getSpriteManager().SaveSpriteIdToCurrentGroup(spriteId);
        this.WriteTextElement(elementName, spriteId);
    }
    
    public void WriteTextElement(String elementName, String elementValue) throws IOException
    {
        //this.WriteTabs();
        this.writer.write("<");
        this.writer.write(elementName);
        this.writer.write(">");
        this.writer.write(elementValue);
        this.writer.write("</");
        this.writer.write(elementName);
        this.writer.write(">");
        //this.writer.newLine();
    }

    public void WriteRectangleElement(Rectangle rectangle) throws IOException
    {
        this.StartElement("Rectangle");
        this.WriteDoubleElement("X", rectangle.getX());
        this.WriteDoubleElement("Y", rectangle.getY());
        this.WriteDoubleElement("Width", rectangle.getWidth());
        this.WriteDoubleElement("Height", rectangle.getHeight());
        this.EndElement();
    }

    public void WriteColorElement(Color color) throws IOException
    {
        this.StartElement("Color");
        this.WriteDoubleElement("A", color.getAlpha());
        this.WriteDoubleElement("R", color.getRed());
        this.WriteDoubleElement("G", color.getGreen());
        this.WriteDoubleElement("B", color.getBlue());
        this.EndElement();
    }

    public void WritePolygonElement(Polygon polygon) throws IOException
    {
        this.StartElement("Polygon");
        
        float[] pointArray = polygon.getPoints();
        
        for (int i = 0; i < pointArray.length; i += 2)
        {
            this.StartElement("Vertex");
            this.WriteDoubleElement("X", pointArray[i]);
            this.WriteDoubleElement("Y", pointArray[i + 1]);
            this.EndElement();
        }
        
        this.EndElement();
    }
    
    public void WritePngElement(String elementName, BufferedImage image) throws IOException
    {         
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ImageIO.write(image, "png", byteArrayOutputStream);
        byteArrayOutputStream.flush();
        this.WriteTextElement(elementName, Base64.encodeBytes(byteArrayOutputStream.toByteArray(), Base64.DO_BREAK_LINES));
        byteArrayOutputStream.close();
    }
    
    public void EndElement() throws IOException
    {
        if (!this.elementNameStack.isEmpty())
        {
            String name = this.elementNameStack.pop();
            
            //this.WriteTabs();
            this.writer.write("</");
            this.writer.write(name);
            this.writer.write(">");
            //this.writer.newLine();
        }
    }
    
    public void Close() throws IOException
    {
        this.writer.close();
    }
    
    private void WriteTabs() throws IOException
    {
        for (int i = 0; i < this.elementNameStack.size(); i++)
        {
            this.writer.write(TabString);
        }
    }
}
